package me.aartikov.alligator.converters;


import java.io.Serializable;

import me.aartikov.alligator.Screen;
import me.aartikov.alligator.helpers.DialogFraction;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.utils.Sequenceable;

/**
 * Creates a dialog fragment of the given class. It also puts a screen to the fragment's arguments if {@code ScreenT} is {@code Serializable} or {@code Parcelable}.
 *
 * @param <ScreenT> screen type
 */

public class DefaultDialogFragmentConverter<ScreenT extends Screen> implements DialogFragmentConverter<ScreenT> {
    private static final String KEY_SCREEN = "me.aartikov.alligator.KEY_SCREEN";

    private Class<ScreenT> mScreenClass;
    private Class<? extends DialogFraction> mDialogFragmentClass;

    public DefaultDialogFragmentConverter(Class<ScreenT> screenClass, Class<? extends DialogFraction> dialogFragmentClass) {
        mScreenClass = screenClass;
        mDialogFragmentClass = dialogFragmentClass;
    }

    @Override

    public DialogFraction createDialogFragment(ScreenT screen) {
        try {
            DialogFraction dialogFragment = mDialogFragmentClass.newInstance();
            if (screen instanceof Serializable) {
                Intent intent = new Intent();
                intent.setParam(KEY_SCREEN, (Serializable) screen);
                if (intent.getParams() == null) {
                    intent.setParams(new IntentParams());
                }
                intent.getParams().setParam(KEY_SCREEN, (Sequenceable) screen);
                dialogFragment.setArguments(intent);
            } else if (screen instanceof Sequenceable) {
                Intent intent = new Intent();
                if (intent.getParams() == null) {
                    intent.setParams(new IntentParams());
                }
                intent.getParams().setParam(KEY_SCREEN, (Sequenceable) screen);
                dialogFragment.setArguments(intent);
            }
//			} else if (screen instanceof Parcelable) {
//				Bundle arguments = new Bundle();
//				arguments.putParcelable(KEY_SCREEN, (Parcelable) screen);
//				dialogFragment.setArguments(arguments);
//			}
            return dialogFragment;
        } catch (InstantiationException e) {
            throw new RuntimeException("Failed to create a dialog fragment", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to create a dialog fragment", e);
        }
    }

    @Override

    @SuppressWarnings("unchecked")
    public ScreenT getScreen(DialogFraction dialogFragment) {
        if (dialogFragment.getArguments() == null) {
            throw new IllegalArgumentException("Fragment has no arguments.");
        } else if (Serializable.class.isAssignableFrom(mScreenClass)) {
            return checkNotNull((ScreenT) dialogFragment.getArguments().getParams().getParam(KEY_SCREEN));
        } else if (Sequenceable.class.isAssignableFrom(mScreenClass)) {
            return checkNotNull((ScreenT) dialogFragment.getArguments().getParams().getParam(KEY_SCREEN));
        } else {
            throw new IllegalArgumentException("Screen " + mScreenClass.getSimpleName() + " should be Serializable or Parcelable.");
        }
    }

    private ScreenT checkNotNull(ScreenT screen) {
        if (screen == null) {
            throw new IllegalArgumentException("Failed to get screen from arguments of fragment.");
        }
        return screen;
    }
}
